package t503

type MyStack struct {
	Items []int
}

// RPush is func
func (m *MyStack) Push(x int) {
	m.Items = append(m.Items, x)
}

// LPop is func
func (m *MyStack) Pop() {
	if len(m.Items) == 0 {
		return
	}
	//pop := m.Items[len(m.Items)-1]
	m.Items = m.Items[:len(m.Items)-1]
	return
}

// LTop is func
func (m *MyStack) Top() int {
	return m.Items[len(m.Items)-1]
}

func (m MyStack) Size() int {
	return len(m.Items)
}

// Clear is func
func (m *MyStack) Clear() {
	m.Items = m.Items[0:0]
}

func nextGreaterElements(nums []int) []int {

	length := len(nums)
	if length == 1 {
		return []int{-1}
	}
	stack := &MyStack{}
	res := make([]int, length)
	for k, _ := range res {
		res[k] = -1
	}

	// key 0  1  2  3  4  0  1  2  3  4
	// val 1  1  1  1  1  1  1  1  1  1
	for i := 0; i < length*2; i++ {
		key := i % length
		cur := nums[key]
		if stack.Size() == 0 {
			stack.Push(key)
			res[key] = -1
			continue
		}

		for stack.Size() > 0 && cur > nums[stack.Top()] {
			res[stack.Top()] = cur
			stack.Pop()
		}
		if stack.Size() > 0 {
			//fmt.Printf("top(%d) key(%d)\n", stack.Top(), key)
			//fmt.Printf("tvl(%d) kvl(%d)\n", nums[stack.Top()], nums[key])
			if stack.Top() == key {
				res[key] = -1
				continue
			}
		}
		stack.Push(key)
		//fmt.Printf("%#v\n", stack.Items)
	}

	//fmt.Printf("RES : %#v\n", res)

	return res
}
